package Threads;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;

import Structs.Msg_rsp;
import Debug.Debug;
import Enums.Type_rsp;

public class C_TCP_out implements Runnable {

	BlockingQueue<Msg_rsp> Req;	
	int port;
	String path;
	Socket socket = null;
	String User;
	String Pass;
	ObjectOutputStream out = null;
	ObjectInputStream in = null;

	public C_TCP_out(BlockingQueue<Msg_rsp> msg,int port,String path) {
		// TODO Auto-generated constructor stub
		this.Req = msg;
		this.port = port;
		this.path = path;
	}

	public boolean tryconnection(String User,String pass,Type_rsp type) throws IOException{
		try {
			ObjectInputStream tmp;
			Msg_rsp msg= new Msg_rsp(null, null, Type_rsp.Ack);
			socket = new Socket(this.path,this.port);
			
			
			if(out==null)
				out = new ObjectOutputStream(socket.getOutputStream());
			out.writeObject(new Msg_rsp(User,pass,type));

			if (in==null){
				in = new ObjectInputStream(socket.getInputStream());
			}
			
			msg = (Msg_rsp) in.readObject();
			
			if(msg.getName().equals("True")){
				if(type==Type_rsp.Login){
					this.User=User;
					this.Pass = pass;
				}
				return true;
			}
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			if(new Debug().isDebug())
				System.out.println("unknownHost");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		int error = 0;
		Debug debug = new Debug();
		Msg_rsp msg = null;
		Thread in=null;
		ArrayList<Msg_rsp> failover = new ArrayList<Msg_rsp>();
		while(true){
			try {
				if(error!=0){
					socket = new Socket(path,port);
					out = new ObjectOutputStream(socket.getOutputStream());
					this.in = new ObjectInputStream(socket.getInputStream());
				}
				
				in = new Thread(new C_TCP_in(this.in,failover));
				in.start();
				
				
				
				if(error!=0){
					out.writeObject(new Msg_rsp(User, Pass, Type_rsp.Login));
					
					if(error>=5)
							System.out.println("Server back online!");
					error=0;
				}
				
				while(true){
					
					
					
					if(new Debug().isDebug())
						System.out.println("im goin to block");
					
					msg = this.Req.take();
					
					if(new Debug().isDebug())
						System.out.println("im goin to work");
					
					out.writeObject(msg);
					if(msg.getType()==Type_rsp.Logout || msg.getType() == Type_rsp.Exit){
						break;
					}
						
				} 
			}catch (IOException e) {
				try {
					in.join();
					new Thread();
					if(error%5==0 && error!=0){
						System.out.println("Server down your requests will be processed!");
						Thread.sleep(5000);
						error=error%5;
					}
					Thread.sleep(1000);
					error++;
					
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					if(new Debug().isDebug())
						System.out.println("io error interrupted error from TCP out");
				}
				
				// TODO: handle exception
			} catch(InterruptedException e){
				if(debug.isDebug())
					System.out.println("Interrupt Error");
			}
			if(msg.getType()==Type_rsp.Logout || msg.getType() == Type_rsp.Exit){
				break;
			}
		}
	}

}
